class LinkView {
    constructor() {
        this.init()
    }

    init() {
        this.clear()
    }

    clear() {
        this.linkView = {}
    }

    /**
     * 
     * @param {Link} link 
     */
    add(link) {
        this.linkView[link.startId] = this.linkView[link.startId] || {}
        this.linkView[link.startId][link.endId] = link
    }

    /**
     * 替换id
     * @param {string | integer} oldId 
     * @param {string | integer} newId 
     */
    update(oldId, newId) {
        if (this.linkView[oldId]) {
            this.linkView[newId] = this.linkView[oldId]
            for (let i in this.linkView[newId]) {
                this.linkView[newId][i].startId = newId
            }
            delete this.linkView[oldId]
        }
        for (let i in this.linkView) {
            if (this.linkView[i][oldId]) {
                this.linkView[i][newId] = this.linkView[i][oldId]
                this.linkView[i][newId].endId = newId
                delete this.linkView[i][oldId]
            }
        }
    }

    /**
     * 删除链接，如果只传入startId，则删除起点或终点为startId的所有link
     * @param {string | integer} startId 
     * @param {string | integer} endId 
     */
    remove(startId, endId) {
        if (endId !== undefined) {
            delete this.linkView[startId][endId]
        } else {
            delete this.linkView[startId]
            for (let i in this.linkView) {
                delete this.linkView[i][startId]
            }
        }
    }

    findView(startId, endId) {
        if (typeof startId === 'string' || typeof startId === 'number') {
            return this.linkView[startId] && this.linkView[startId][endId]
        }
        return this.linkView[startId.startId] && this.linkView[startId.startId][startId.endId]
    }

    /**
     * 根据节点id找出与其相连的线
     * @param {string} startOrEndId 
     */
    findViews(startOrEndId) {
        let views = []
        if (this.linkView[startOrEndId]) {
            for (let i in this.linkView[startOrEndId]) {
                views.push(this.linkView[startOrEndId][i])
            }
        }
        for (let i in this.linkView) {
            for (let j in this.linkView[i]) {
                if (j == startOrEndId) {
                    views.push(this.linkView[i][j])
                }
            }
        }
        return views
    }

    findViewByJointId(jointId) {
        for (let i in this.linkView) {
            for (let j in this.linkView[i]) {
                if (this.linkView[i][j].jointInstance.id === jointId) {
                    return this.linkView[i][j]
                }
            }
        }
    }

    /**
     * 通过endId寻找startId
     * @param {string} endId 
     * @param {boolean} recursive 递归查询
     * @return 返回字符串数组
     */
    getStartIdsByEndId(endId, recursive) {
        let toSearch = [endId],
            searched = {} // 搜过的节点（包括当前点和所有前置点)

        while (toSearch.length > 0) {
            let id = toSearch.shift()
            if (searched[id]) {
                continue
            }
            searched[id] = true
            for (let i in this.linkView) {
                if (this.linkView[i][id]) {
                    searched[i] = false // 是前置点，还未递归搜索过
                    if (recursive) {
                        toSearch.push(i)
                    }
                }
            }
        }
        let ids = []
        for (let i in searched) {
            if (i != endId) {
                ids.push(i)
            }
        }
        return ids
    }

    /**
     * 通过startId寻找endId
     * @param {string} startId 
     * @param {boolean} recursive 递归查询
     * @return 返回字符串数组
     */
    getEndIdsByStartId(startId, recursive) {
        let toSearch = [startId],
            searched = {} // 搜过的节点（包括当前点和所有后置点)

        while (toSearch.length > 0) {
            let id = toSearch.shift()
            if (searched[id]) {
                continue
            }
            searched[id] = true
            for (let i in this.linkView[id]) {
                searched[i] = false // 是后置点，还未递归搜索过
                if (recursive) {
                    toSearch.push(i)
                }
            }
        }
        let ids = []
        for (let i in searched) {
            if (i != startId) {
                ids.push(i)
            }
        }
        return ids
    }

    getModel() {
        let model = []
        for (let i in this.linkView) {
            for (let j in this.linkView[i]) {
                model.push(this.linkView[i][j].model)
            }
        }
        return model
    }

    refresh() {
        for (let i in this.linkView) {
            for (let j in this.linkView[i]) {
                // don't curve for now 刷新有问题
                // this.linkView[i][j].setCurve()
            }
        }
    }
}

export default LinkView